﻿/*
 * Copyright 2008 Pimm Hogeling, Karim Sempel and Demian Sempel
 * 
 * This file is part of 8bitplays.
 * 
 * 8bitplays is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 * 
 * 8bitplays is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with 8bitplays. If not, see <http://www.gnu.org/licenses/>.
 */
package nl.sandmen.team.loaders {
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.TimerEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	import flash.utils.Timer;
	import nl.sandmen.team.data.Album;
	import nl.sandmen.team.data.Track;
	import nl.sandmen.team.events.DiscographyLoaderEvent;
	/**
	 * @author Team Sandmen
	 */
	public class DiscographyLoader extends URLLoader {
		private var albumDivs:XMLList;
		private var currentNode:uint;
		private var nodeParser:Timer;
		private var totalNodes:uint;
		public function DiscographyLoader():void {
			dataFormat = URLLoaderDataFormat.TEXT;
			addEventListener(Event.COMPLETE, loadComplete);
			addEventListener(IOErrorEvent.IO_ERROR, ioError);
		}
		private function endOfList(e:TimerEvent):void {
			dispatchEvent(new DiscographyLoaderEvent(DiscographyLoaderEvent.END_OF_LIST));
			albumDivs = null;
			nodeParser = null;
		}
		private function ioError(e:IOErrorEvent):void {
			
		}
		private function loadComplete(e:Event):void {
			removeEventListener(Event.COMPLETE, loadComplete);
			removeEventListener(IOErrorEvent.IO_ERROR, ioError);
			try {
				const xml:XML = new XML(data);
			} catch (e:Error) {
				
				return;
			}
			startParsing(xml);
		}
		public function loadDiscography(albums:uint, page:uint, urlRequestHeaders:Array):void {
			var parameters:URLVariables = new URLVariables();
			parameters.show = albums;
			parameters.page = page;
			var request:URLRequest = new URLRequest("http://8bitpeoples.com/discography?" + parameters.toString());
			if (urlRequestHeaders) {
				request.requestHeaders = urlRequestHeaders;
			}
			load(request);
		}
		private function parseNextNode(e:TimerEvent):void {
			const node:XML = albumDivs[++currentNode];
			const albumInfo:XML = node.div.(attribute("class") == "albumInfo")[0];
			const anchors:XMLList = albumInfo.a;
			var trackList:Array = new Array();
			for each (var anchor:XML in anchors) {
				// Since 8bitpeoples tends to also have some source files available (such as NSF files), so we'll check if they have
				//  mp3 extensions. This doesn't garauntee that they're really in valid mp3 format, but it's an easy check.
				if (anchor.@href.substr( -3, 3).toLowerCase() === "mp3") {
					trackList.push(new Track(anchor.text().substr(1), anchor.@href));
				}
			}
			// 8bitpeoples also tends to have 'empty' albums: albums with no downloadable tracks. If the trackList Array object is
			//  empty we'll abort parsing this node.
			if (!trackList.length) {
				return;
			}
			const id:uint = uint(node.a.@name.substr(3));
			const albumName:String = albumInfo.div.(attribute("class") == "albumName")[0].text();
			const albumArtist:String = albumInfo.div.(attribute("class") == "albumArtist").a[0].text();
			dispatchEvent(new DiscographyLoaderEvent(DiscographyLoaderEvent.NEW_ALBUM, new Album(albumArtist, albumName, id, trackList)));
		}
		private function startParsing(xml:XML):void {
			albumDivs = xml.body.div.(@id == "discographyContentWrapper").div;
			currentNode = 0;
			// To prevent a CPU kill the discography XHTML will be parsed one node at a time. Every 2 ms the parseNextNode method
			//  is called, which will parse a node.
			nodeParser = new Timer(2, albumDivs.length() - 2);
			nodeParser.addEventListener(TimerEvent.TIMER, parseNextNode);
			nodeParser.addEventListener(TimerEvent.TIMER_COMPLETE, endOfList);
			nodeParser.start();
		}
	}
}